package com.dankegongyu.lib.common.util;

import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import androidx.annotation.NonNull;
import android.util.DisplayMetrics;
import android.util.Pair;
import android.view.Display;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;

/**
 * 监听键盘显示隐藏
 *
 * @author wupuquan
 * @version 1.0
 * @since 2018/7/31 15:36
 */
public class KeyboardObserver {

    private Activity mActivity;
    private View mDecorView;
    private GlobalLayoutListener mGlobalLayoutListener;

    private KeyboardObserver(Activity activity, OnKeyboardListener onKeyboardListener) {
        this.mActivity = activity;
        this.mDecorView = mActivity.getWindow().getDecorView();
        this.mGlobalLayoutListener = new GlobalLayoutListener(onKeyboardListener);
        addSoftKeyboardChangedListener();
    }

    public static KeyboardObserver create(@NonNull Activity activity, OnKeyboardListener onKeyboardListener) {
        return new KeyboardObserver(activity, onKeyboardListener);
    }

    /**
     * 注册软键盘状态变化监听
     */
    private void addSoftKeyboardChangedListener() {
        if (mGlobalLayoutListener != null && mDecorView != null) {
            removeSoftKeyboardChangedListener();
            mDecorView.getViewTreeObserver().addOnGlobalLayoutListener(mGlobalLayoutListener);
        }
    }

    /**
     * 取消软键盘状态变化监听
     */
    private void removeSoftKeyboardChangedListener() {
        if (mGlobalLayoutListener != null && mDecorView != null) {
            mDecorView.getViewTreeObserver().removeOnGlobalLayoutListener(mGlobalLayoutListener);
        }
    }

    /**
     * 释放资源
     */
    public void release() {
        removeSoftKeyboardChangedListener();
        mGlobalLayoutListener = null;
    }

    /**
     * 判断键盘是否显示
     */
    public Pair<Boolean, Integer> isKeyboardShowing(Context context, View decorView) {
        Rect outRect = new Rect();
        // 指当前Window实际的可视区域大小，通过decorView获取到程序显示的区域，包括标题栏，但不包括状态栏
        decorView.getWindowVisibleDisplayFrame(outRect);
        int displayScreenHeight = getDisplayScreenHeight(context);
        // 如果屏幕高度和Window可见区域高度差值大于0，则表示软键盘显示中，否则软键盘为隐藏状态
        int heightDifference = displayScreenHeight - outRect.bottom;
        //noinspection unchecked
        return new Pair(heightDifference > 0, heightDifference);
    }

    /**
     * 获取的当前显示屏幕的高度(不包含虚拟键所占空间)
     */
    public static int getDisplayScreenHeight(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        if (windowManager == null) {
            return 0;
        }
        Display display = windowManager.getDefaultDisplay();
        //获取的像素宽高不包含虚拟键所占空间
        DisplayMetrics metric = new DisplayMetrics();
        display.getMetrics(metric);
        return metric.heightPixels;
    }

    public interface OnKeyboardListener {
        void onKeyboardChange(boolean shown, int keyboardHeight);
    }

    public class GlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {

        private boolean isKeyboardShown;

        private OnKeyboardListener onKeyboardListener;

        public GlobalLayoutListener(OnKeyboardListener onKeyboardListener) {
            this.isKeyboardShown = false;
            this.onKeyboardListener = onKeyboardListener;
        }

        @Override
        public void onGlobalLayout() {
            if (onKeyboardListener != null && mDecorView != null) {
                Pair<Boolean, Integer> pair = isKeyboardShowing(mActivity, mDecorView);
                if (pair.first) {
                    onKeyboardListener.onKeyboardChange(isKeyboardShown = true, pair.second);
                } else if (isKeyboardShown) {
                    onKeyboardListener.onKeyboardChange(isKeyboardShown = false, pair.second);
                }
            }
        }
    }
}
